import { Logger } from "../../common/log/Logger";

/**
 *  装饰器执行顺序：
 *  1. 参数装饰器-》方法装饰器-》访问符装饰器-》属性装饰器-》  应用到每个实例成员
 *  2. 参数装饰器-》方法装饰器-》访问符装饰器-》属性装饰器-》  应用到每个静态成员
 *  3. 参数装饰器应用到构造函数
 *  4. 类装饰器应用到类
 * 
 */


/**
 * 方法计时统计装饰
 * @param desc 
 * @returns 
 */
export const countTime = function (desc: string) {
    return function (target: any, funcName: string, descriptor: PropertyDescriptor) {
        const method = descriptor.value;
        descriptor.value = function (...args: any[]) {
            let start = new Date().valueOf();

            try {
                return method.apply(this, args);
            } finally {
                let end = new Date().valueOf();
                Logger.debug(`start: ${start} end: ${end} consume: ${end - start}`);
            }
        }
    };
}

/**
 * 重构构造
 */
export const testRewriteCtor = function (target: any) {
    return class extends target {

    }
}

function capitalizeFirstLetter(str: string) {
    return str.charAt(0).toUpperCase() + str.slice(1);
}

export function observable(target: any, key: string): any {
    // prop -> onPropChange
    const targetKey = "on" + capitalizeFirstLetter(key) + "Change";

    target[targetKey] = function (fn: (prev: any, next: any) => void) {
        let prev = this[key];
        Reflect.defineProperty(this, key, {
            set(next) {
                fn(prev, next);
                prev = next;
            }
        })
    };
}